import fast_network_analysis as fna

import numpy as np

from scipy import *
import scipy.io as io

from brian import *

# --------- large event detection here

def search_big_events(vm_trace,time,spiketime,big_event_ampli_limit,big_event_time_limit):
# Calculate the big events in a trace.
#   INPUT: 
#       vm_trace:           the vm trace
#       time:               just a vector containing the time of each step
#                           (same size as vm_trace)
#       spike_threshold:     time of the spikes
#       big_event_ampli_limit: compute events only larger than that.
#                           (typically 2-3 mV in order not to blow up the
#                           calculations!)
#       big_event_time_limit: this is the window in which big events are looked for. 
#                           Usually it should be smaller of the membrane time constant (about 0.005 ms in my invivo data - i use 3 ms)
#       
#       
#   OUTPUT: 
#           bigevent.ampli contains the amplitude of the events
#           bigevent.binstart contains the bin of the onset of big events
#           bigevent.binduration contains the duration of the big events
#           bigevent.voltstart contains the starting voltage of the event
#           bigevent.spiketrigger is 0 if the event did not trigger a
#                                 spike, 1 if the event triggered a spike.
#
    
    dt=time[1]-time[0]
    spikebin=np.round(spiketime/dt)
        
    binlimit=np.round(big_event_time_limit/dt)
    nbins=vm_trace.size
    deltav=vm_trace[binlimit-1 :] - vm_trace[0:nbins-binlimit+1] 
    
    suprathrev=(deltav>big_event_ampli_limit).nonzero()

    diffsuprathrev=diff(suprathrev[0], n=1, axis=0)
    blockstart=(diffsuprathrev>1).nonzero()
    
    blockstart=blockstart[0]+1
    blockstart=concatenate((array([0]),blockstart)) 
    
    timemin=0.005
    
    difftime=time[suprathrev[0][blockstart[1:]]]- time[suprathrev[0][blockstart[0 :-1]]]
    
    closestarts=(difftime<timemin).nonzero()

    blockstart=np.delete(blockstart,[closestarts[0]+1])
    
    blockend=blockstart[1:]-1
    
    blockend=concatenate((blockend,array([size(suprathrev[0])-1])))

    nevents=size(blockstart)
    
    bigevent={}
    bigevent['ampli']=[]
    bigevent['binstart']=[]
    bigevent['binduration']=[]
    bigevent['voltstart']=[]
    bigevent['spiketrigger']=[]

    for ii in range(0,nevents):
        npoints=blockend[ii]-blockstart[ii]+1
        
        maxvoltdiff=[]
        stopindex=[]
        for jj in range(0,npoints):
            stb_a=minimum(suprathrev[0][blockstart[ii]]+jj+1,size(vm_trace))
            stb_b=minimum(suprathrev[0][blockstart[ii]]+jj+1+binlimit,size(vm_trace))
            
            maxvoltdiff.append(max(vm_trace[stb_a : stb_b+1]-vm_trace[stb_a])) 
            stopindex.append(argmax(vm_trace[stb_a : stb_b+1]-vm_trace[stb_a]))
                
        bigevent['ampli'].append(max(maxvoltdiff))
        startindex=argmax(maxvoltdiff)
        bigevent['binstart'].append(suprathrev[0][blockstart[ii]] + startindex+1)
        bigevent['binduration'].append(stopindex[startindex] - 0)
        bigevent['voltstart'].append(vm_trace[suprathrev[0][blockstart[ii]]+ startindex])
        
        binstop=bigevent['binstart'][ii]+bigevent['binduration'][ii]
        
        if spikebin.size:
            boolspiketrigger=min(abs(spikebin-binstop))
            sp_limit=0.005 # all the events close more than this to a spike are considered "spke-triggering"
            sp_limit_bin=np.round(sp_limit/dt)
            if boolspiketrigger<sp_limit_bin:
                bigevent['spiketrigger'].append([1])
            else:
                bigevent['spiketrigger'].append([0])
        else:
           bigevent['spiketrigger'].append([0]) 
    return bigevent
                                     
        
                                        
    




    
            
            
